﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

/*
* 源码已托管：https://gitee.com/dlgcy/WPFTemplateLib
*/
namespace WPFTemplateLib.Enhance
{
	/// <summary>
	/// 可暂停事件通知的 <see cref="ObservableCollection&lt;T&gt;"/> <para/>
	/// 修改自：https://www.cnblogs.com/wzwyc/p/16012007.html
	/// </summary>
	/// <typeparam name="T"></typeparam>
	public class SuspendableObservableCollection<T> : ObservableCollection<T>, ISuspendUpdate
	{
		private bool _updatesEnabled = true;
		private bool _collectionChanged = false;

		/// <inheritdoc />
		public void ResumeUpdate()
		{
			_updatesEnabled = true;
			if (_collectionChanged)
			{
				_collectionChanged = false;
				OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
			}
		}

		/// <inheritdoc />
		public void SuspendUpdate()
		{
			_updatesEnabled = false;
		}

		/// <inheritdoc />
		protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
		{
			if (_updatesEnabled)
			{
				base.OnCollectionChanged(e);
			}
			else
			{
				_collectionChanged = true;
			}
		}
	}

	/// <summary>
	/// [接口] 暂停更新
	/// </summary>
	public interface ISuspendUpdate
	{
		/// <summary>
		/// 暂停更新
		/// </summary>
		void SuspendUpdate();

		/// <summary>
		/// 恢复更新
		/// </summary>
		void ResumeUpdate();
	}

	/// <summary>
	/// 暂停更新范围
	/// </summary>
	/// <example>
	///	<code>
	///	SuspendableObservableCollection&lt;string&gt; LogItems { get; set; } = new();
	/// LogItems.Insert(0, "状态更新");
	/// if (LogItems.Count &gt; 30)
	/// {
	///		//进入时暂停更新，离开时自动恢复
	///		using (var scope = new SuspendUpdateScope(LogItems))
	///		{
	///			while (LogItems.Count &gt; 10)
	///			{
	///				LogItems.RemoveAt(LogItems.Count - 1);
	///			}
	///		}
	/// }
	/// </code>
	/// </example>
	public class SuspendUpdateScope : IDisposable
	{
		private ISuspendUpdate _parent;

		public SuspendUpdateScope(ISuspendUpdate parent)
		{
			_parent = parent; 
			parent.SuspendUpdate();
		}

		/// <inheritdoc />
		public void Dispose()
		{
			_parent.ResumeUpdate();
		}
	}
}
